<?php
/** 
* Barcode Helper class file. 
* 
* Simplifies creating charts with the google charts api. 
* 
* Copyright (c) 2010 Remi DUDREUIL 
* 
* Licensed under The MIT License 
* Redistributions of files must retain the above copyright notice. 
* 
* @filesource 
* @copyright     Copyright (c) 2010 Remi DUDREUIL 
* @link             http://net.productions.free.fr 
* @license       http://www.opensource.org/licenses/mit-license.php The MIT License 
*/ 
class BarcodeHelper extends AppHelper 
    { 
        /** 
        * ***** DÃ©finition des variables ***** 
        */ 
         
        var $CODE; 
        var $FULLCODE; 
        var $TYPE; 
        var $HEIGHT; 
        var $WIDTH; 
        var $CODEWIDTH; 
        var $CALMZONE; 
        var $HR; 
        var $SHOWTYPE; 
        var $BACKGROUND; 
        var $FOREGROUND; 
        var $FILETYPE; 
        var $ENCODED; 
        var $IH = NULL; 
         
        /** 
        * DÃ©finition des symbologies 
        */ 
        var $C128 = array( 
                    0 => "11011001100",     1 => "11001101100",     2 => "11001100110", 
                    3 => "10010011000",     4 => "10010001100",     5 => "10001001100", 
                    6 => "10011001000",     7 => "10011000100",     8 => "10001100100", 
                    9 => "11001001000",     10 => "11001000100",    11 => "11000100100", 
                    12 => "10110011100",    13 => "10011011100",    14 => "10011001110", 
                    15 => "10111001100",    16 => "10011101100",    17 => "10011100110", 
                    18 => "11001110010",    19 => "11001011100",    20 => "11001001110", 
                    21 => "11011100100",    22 => "11001110100",    23 => "11101101110", 
                    24 => "11101001100",    25 => "11100101100",    26 => "11100100110", 
                    27 => "11101100100",    28 => "11100110100",    29 => "11100110010", 
                    30 => "11011011000",    31 => "11011000110",    32 => "11000110110", 
                    33 => "10100011000",    34 => "10001011000",    35 => "10001000110", 
                    36 => "10110001000",    37 => "10001101000",    38 => "10001100010", 
                    39 => "11010001000",    40 => "11000101000",    41 => "11000100010", 
                    42 => "10110111000",    43 => "10110001110",    44 => "10001101110", 
                    45 => "10111011000",    46 => "10111000110",    47 => "10001110110", 
                    48 => "11101110110",    49 => "11010001110",    50 => "11000101110", 
                    51 => "11011101000",    52 => "11011100010",    53 => "11011101110", 
                    54 => "11101011000",    55 => "11101000110",    56 => "11100010110", 
                    57 => "11101101000",    58 => "11101100010",    59 => "11100011010", 
                    60 => "11101111010",    61 => "11001000010",    62 => "11110001010", 
                    63 => "10100110000",    64 => "10100001100",    65 => "10010110000", 
                    66 => "10010000110",    67 => "10000101100",    68 => "10000100110", 
                    69 => "10110010000",    70 => "10110000100",    71 => "10011010000", 
                    72 => "10011000010",    73 => "10000110100",    74 => "10000110010", 
                    75 => "11000010010",    76 => "11001010000",    77 => "11110111010", 
                    78 => "11000010100",    79 => "10001111010",    80 => "10100111100", 
                    81 => "10010111100",    82 => "10010011110",    83 => "10111100100", 
                    84 => "10011110100",    85 => "10011110010",    86 => "11110100100", 
                    87 => "11110010100",    88 => "11110010010",    89 => "11011011110", 
                    90 => "11011110110",    91 => "11110110110",    92 => "10101111000", 
                    93 => "10100011110",    94 => "10001011110",    95 => "10111101000", 
                    96 => "10111100010",    97 => "11110101000",    98 => "11110100010", 
                    99  => "10111011110",    // 99 et 'c' sont identiques ne nous sert que pour le checksum 
                    100 => "10111101110",    // 100 et 'b' sont identiques ne nous sert que pour le checksum 
                    101 => "11101011110",    // 101 et 'a' sont identiques ne nous sert que pour le checksum 
                    102 => "11110101110",    // 102 correspond Ã  FNC1 ne nous sert que pour le checksum 
                    'c' => "10111011110",   'b' => "10111101110",   'a' => "11101011110", 
                    'A' => "11010000100",   'B' => "11010010000",   'C' => "11010011100", 
                    'S' => "1100011101011" 
                ); 
         
        var $C25 =  array( 
                    0 => "11331",           1 => "31113", 
                    2 => "13113",           3 => "33111", 
                    4 => "11313",           5 => "31311", 
                    6 => "13311",           7 => "11133", 
                    8 => "31131",           9 => "13131", 
                    'D' => "111011101",       'F' => "111010111", // Code 2 parmi 5 
                    'd' => "1010",          'f' => "11101"   // Code 2/5 entrelacÃ© 
                ); 
                      
        var $C39 =  array( 
                    '0' => "101001101101",  '1' => "110100101011",  '2' => "101100101011", 
                    '3' => "110110010101",  '4' => "101001101011",  '5' => "110100110101", 
                    '6' => "101100110101",  '7' => "101001011011",  '8' => "110100101101", 
                    '9' => "101100101101",  'A' => "110101001011",  'B' => "101101001011", 
                    'C' => "110110100101",  'D' => "101011001011",  'E' => "110101100101", 
                    'F' => "101101100101",  'G' => "101010011011",  'H' => "110101001101", 
                    'I' => "101101001101",  'J' => "101011001101",  'K' => "110101010011", 
                    'L' => "101101010011",  'M' => "110110101001",  'N' => "101011010011", 
                    'O' => "110101101001",  'P' => "101101101001",  'Q' => "101010110011", 
                    'R' => "110101011001",  'S' => "101101011001",  'T' => "101011011001", 
                    'U' => "110010101011",  'V' => "100110101011",  'W' => "110011010101", 
                    'X' => "100101101011",  'Y' => "110010110101",  'Z' => "100110110101", 
                    '-' => "100101011011",  '.' => "110010101101",  ' ' => "100110101101", 
                    '$' => "100100100101",  '/' => "100100101001",  '+' => "100101001001", 
                    '%' => "101001001001",  '*' => "100101101101" 
                ); 
                      
        var $codabar = array( 
                    '0' => "101010011",     '1' => "101011001",     '2' => "101001011", 
                    '3' => "110010101",     '4' => "101101001",     '5' => "110101001", 
                    '6' => "100101011",     '7' => "100101101",     '8' => "100110101", 
                    '9' => "110100101",     '-' => "101001101",     '$' => "101100101", 
                    ':' => "1101011011",    '/' => "1101101011",    '.' => "1101101101", 
                    '+' => "1011011011",    'A' => "1011001001",    'B' => "1010010011", 
                    'C' => "1001001011",    'D' => "1010011001" 
                ); 
                 
        var $MSI = array( 
                    0 => "100100100100",  
                    1 => "100100100110",  
                    2 => "100100110100",  
                    3 => "100100110110",  
                    4 => "100110100100",  
                    5 => "100110100110",  
                    6 => "100110110100",  
                    7 => "100110110110",  
                    8 => "110100100100",  
                    9 => "110100100110",  
                    'D' => "110",  
                    'F' => "1001" 
                ); 
                      
        var $C11 = array( 
                    '0' => "101011",  
                    '1' => "1101011",  
                    '2' => "1001011",  
                    '3' => "1100101",  
                    '4' => "1011011",  
                    '5' => "1101101",  
                    '6' => "1001101",  
                    '7' => "1010011",  
                    '8' => "1101001",  
                    '9' => "110101",  
                    '-' => "101101",  
                    'S' => "1011001"  
                ); 
     
        var $postnet = array( 
                    '0' => "11000",  
                    '1' => "00011",  
                    '2' => "00101",  
                    '3' => "00110",  
                    '4' => "01001",  
                    '5' => "01010",  
                    '6' => "01100",  
                    '7' => "10001",  
                    '8' => "10010",  
                    '9' => "10100" 
                ); 
     
        var $kix = array(       //0=haut, 1=bas, 2=milieu, 3=toute la hauteur 
                    '0' => '2233',          '1' => '2103',          '2' => '2130', 
                    '3' => '1203',          '4' => '1230',          '5' => '1100', 
                    '6' => '2013',          '7' => '2323',          '8' => '2310', 
                    '9' => '1023',          'A' => '1010',          'B' => '1320', 
                    'C' => '2031',          'D' => '2301',          'E' => '2332', 
                    'F' => '1001',          'G' => '1032',          'H' => '1302', 
                    'I' => '0213',          'J' => '0123',          'K' => '0110', 
                    'L' => '3223',          '2' => '3210',          'N' => '3120', 
                    'O' => '0231',          'P' => '0101',          'Q' => '0132', 
                    'R' => '3201',          'S' => '3232',          'T' => '3102', 
                    'U' => '0011',          'V' => '0321',          'W' => '0312', 
                    'X' => '3021',          'Y' => '3021',          'Z' => '3322' 
                ); 
     
        var $CMC7 = array( 
                    0 => "0,3-0,22|2,1-2,24|4,0-4,8|4,18-4,25|8,0-8,8|8,18-8,25|12,0-12,8|12,18-12,25|14,1-14,24|16,3-16,22", 
                    1 => "0,5-0,12|0,17-0,25|4,3-4,10|4,17-4,25|6,2-6,9|6,17-6,25|8,1-8,25|10,0-10,25|14,14-14,25|16,14-16,25", 
                    2 => "0,2-0,9|0,17-0,25|2,0-2,9|2,16-2,25|6,0-6,6|6,13-6,25|10,0-10,6|10,11-10,17|10,20-10,25|12,0-12,6|12,10-12,16|12,20-12,25|14,0-14,14|14,20-14,25|16,2-16,13|16,20-16,25", 
                    3 => "0,2-0,9|0,17-0,23|4,0-4,9|4,17-4,25|6,0-6,8|6,18-6,25|10,0-10,7|10,10-10,16|10,19-10,25|12,0-12,7|12,10-12,16|12,19-12,25|14,0-14,25|16,2-16,12|16,14-16,23", 
                    4 => "0,6-0,21|4,4-4,21|6,3-6,11|6,16-6,21|8,2-8,10|8,16-8,21|12,0-12,8|12,15-12,25|14,0-14,8|14,15-14,25|16,0-16,8|16,15-16,25", 
                    5 => "0,0-0,14|0,19-0,25|2,0-2,14|2,19-2,25|4,0-4,6|4,9-4,14|4,19-4,25|6,0-6,6|6,9-6,14|6,19-6,25|10,0-10,6|10,9-10,14|10,19-10,25|14,0-14,6|14,9-14,25|16,0-16,6|16,11-16,23", 
                    6 => "0,2-0,23|2,0-2,25|4,0-4,6|4,10-4,15|4,19-4,25|8,0-8,6|8,10-8,15|8,19-8,25|10,0-10,6|10,10-10,15|10,19-10,25|14,0-14,7|14,10-14,25|16,2-16,7|16,12-16,23", 
                    7 => "0,0-0,9|0,19-0,25|4,0-4,6|4,16-4,25|8,0-8,6|8,12-8,21|10,0-10,6|10,9-10,19|12,0-12,17|14,0-14,15|16,0-16,13", 
                    8 => "0,2-0,10|0,15-0,23|2,0-2,11|2,14-2,25|6,0-6,6|6,10-6,15|6,19-6,25|8,0-8,6|8,10-8,15|8,19-8,25|10,0-10,6|10,10-10,15|10,19-10,25|14,0-14,11|14,14-14,25|16,2-16,10|16,15-16,23", 
                    9 => "0,2-0,13|0,18-0,23|2,0-2,15|2,18-2,25|6,0-6,6|6,10-6,15|6,19-6,25|8,0-8,6|8,10-8,15|8,19-8,25|12,0-12,6|12,10-12,15|12,19-12,25|14,0-14,25|16,2-16,23", 
                    'A' => "0,4-0,15|0,19-0,24|2,4-2,15|2,19-2,24|4,4-4,15|4,19-4,24|8,4-8,15|8,19-8,24|10,4-10,15|10,19-10,24|12,4-12,15|12,19-12,24|16,4-16,15|16,19-16,24", 
                    'B' => "0,9-0,24|4,7-4,22|6,6-6,21|8,5-8,20|10,4-10,19|12,3-12,18|16,1-16,16", 
                    'C' => "0,4-0,12|0,16-0,24|2,4-2,12|2,16-2,24|4,4-4,12|4,16-4,24|6,4-6,12|6,16-6,24|10,7-10,21|12,7-12,21|16,7-16,21", 
                    'D' => "0,10-0,24|2,10-2,24|6,10-6,24|8,10-8,24|10,4-10,24|12,4-12,24|16,4-16,24", 
                    'E' => "0,7-0,12|0,16-0,25|2,5-2,23|4,3-4,21|6,1-6,19|8,0-8,18|12,3-12,21|16,7-16,12|16,16-16,25", 
                ); 
                 
        var $EANbars = array('A' => array( 
                    0 => "0001101",         1 => "0011001", 
                    2 => "0010011",         3 => "0111101", 
                    4 => "0100011",         5 => "0110001", 
                    6 => "0101111",         7 => "0111011", 
                    8 => "0110111",         9 => "0001011" 
                    ), 
                    'B' => array( 
                    0 => "0100111",         1 => "0110011", 
                    2 => "0011011",         3 => "0100001", 
                    4 => "0011101",         5 => "0111001", 
                    6 => "0000101",         7 => "0010001", 
                    8 => "0001001",         9 => "0010111" 
                    ), 
                    'C' => array( 
                    0 => "1110010",         1 => "1100110", 
                    2 => "1101100",         3 => "1000010", 
                    4 => "1011100",         5 => "1001110", 
                    6 => "1010000",         7 => "1000100", 
                    8 => "1001000",         9 => "1110100" 
                    ) 
                ); 
         
        var $EANparity = array( 
                    0 => array('A','A','A','A','A','A'), 
                    1 => array('A','A','B','A','B','B'), 
                    2 => array('A','A','B','B','A','B'), 
                    3 => array('A','A','B','B','B','A'), 
                    4 => array('A','B','A','A','B','B'), 
                    5 => array('A','B','B','A','A','B'), 
                    6 => array('A','B','B','B','A','A'), 
                    7 => array('A','B','A','B','A','B'), 
                    8 => array('A','B','A','B','B','A'), 
                    9 => array('A','B','B','A','B','A') 
                ); 
         
        /** 
        * Constructeur // est appelÃ© automatiquement Ã  l'instanciation de l'objet 
        */ 
        function barcode() 
        { 
            $this->CODE = ''; 
            $this->FULLCODE = 'NO CODE SET'; 
            $this->TYPE = 'ERR'; 
            $this->HEIGHT = 15; 
            $this->WIDTH = 0; 
            $this->CALMZONE = 10; 
            $this->HR = 'AUTO'; 
            $this->SHOWTYPE = 'Y'; 
            $this->FOREGROUND = hexdec('#000000'); 
            $this->BACKGROUND = hexdec('#FFFFFF'); 
            $this->FILETYPE = 'PNG'; 
            $this->ENCODED = ''; 
            // detruire eventuellement l'image existante 
            if ($this->IH) imagedestroy($this->IH); 
            $this->IH = NULL; 
        } 
         
        /** 
        * Set Barcode Type 
        */ 
        function setType($type) 
        { 
            $this->TYPE = $type; 
        } 
        /** 
        * Set Barcode String 
        */ 
        function setCode($code) 
        { 
            $this->CODE = $code; 
        } 
        /** 
        * Set Image Height and Extra-Width 
        */ 
        function setSize($height, $width=0, $calmZone=0) 
        { 
            $this->HEIGHT = ($height > 15 ? $height : 15); 
            $this->WIDTH = ($width > 0 ? $width : 0); 
            $this->CALMZONE = ($calmZone > 10 ? $calmZone : 10); 
        } 
        /** 
        * Set the Printed Text under Bars 
        */ 
        function setText($text='AUTO') 
        { 
            $this->HR = $text; 
        } 
        /** 
        * Disable CodeType printing 
        */ 
        function hideCodeType() 
        { 
            $this->SHOWTYPE = 'N'; 
        } 
        /** 
        * Set Colors 
        */ 
        function setColors($fg, $bg='#FFFFFF') 
        { 
            $this->FOREGROUND = hexdec($fg); 
            $this->BACKGROUND = hexdec($bg); 
        } 
        /** 
        * Set File Type (PNG, GIF or JPG) 
        */ 
        function setFiletype($ft='PNG') 
        { 
            $ft = strtoupper($ft); 
            $this->FILETYPE = ($ft == 'GIF' ? 'GIF' : ($ft == 'JPG' ? 'JPG' : 'PNG')); 
        } 
         
        /** 
        * VÃ©rification du Code 
        *  
        * calcul ou vÃ©rification du Checksum 
        */ 
        function checkCode() 
        { 
            switch( $this->TYPE ) { 
                case "C128C" : 
                 
                    if (preg_match("/^[0-9]{2,48}$/", $this->CODE)) 
                    { 
                        $tmp = strlen($this->CODE); 
                        if (($tmp%2)!=0) $this->FULLCODE = '0'.$this->CODE; 
                        else             $this->FULLCODE = $this->CODE; 
                    } 
                    else 
                    { 
                      $this->TYPE = "ERR"; 
                      $this->FULLCODE = "CODE 128C REQUIRES DIGITS ONLY"; 
                      break; 
                    } 
                     
                case "C128" : 
                     
                    $carok = true; 
                    $long = strlen( $this->CODE ); 
                    $i = 0; 
                    while (($carok) && ($i<$long)) 
                    { 
                        $tmp = ord( $this->CODE{$i} ) ; 
                        if (($tmp < 32) OR ($tmp > 126)) $carok = false; 
                        $i++; 
                    } 
                    if ($carok) $this->FULLCODE = $this->CODE; 
                    else 
                    { 
                      $this->TYPE = "ERR"; 
                      $this->FULLCODE = "UNAUTHORIZED CHARS IN 128 CODE"; 
                    } 
                 
                  break; 
                case "UPC" : 
                 
                    $this->CODE = '0'.$this->CODE; 
                    $this->TYPE = 'EAN'; 
                     
                case "EAN" : 
                 
                    $long = strlen( $this->CODE ) ; 
                    $factor = 3; 
                    $checksum = 0; 
                     
                    if (preg_match("/^[0-9]{8}$/", $this->CODE) OR preg_match("/^[0-9]{13}$/", $this->CODE)) 
                    { 
                    
                        for ($index = ($long - 1); $index > 0; $index--) 
                        { 
                            $checksum += intval($this->CODE{$index-1}) * $factor ; 
                            $factor = 4 - $factor ; 
                        } 
                        $cc = ( (1000 - $checksum) % 10 ) ; 
                 
                        if ( substr( $this->CODE, -1, 1) != $cc ) 
                        { 
                            $this->TYPE = "ERR"; 
                            $this->FULLCODE = "CHECKSUM ERROR IN EAN/UPC CODE"; 
                        } 
                        else $this->FULLCODE = $this->CODE; 
                    
                    } 
                    elseif (preg_match("/^[0-9]{7}$/", $this->CODE) OR preg_match("/^[0-9]{12}$/", $this->CODE)) 
                    { 
                    
                        for ($index = $long; $index > 0; $index--) { 
                            $checksum += intval($this->CODE{$index-1}) * $factor ; 
                            $factor = 4 - $factor ; 
                        } 
                        $cc = ( ( 1000 - $checksum ) % 10 ) ; 
                 
                        $this->FULLCODE = $this->CODE.$cc ; 
                    
                    } 
                    else 
                    { 
                      $this->TYPE = "ERR"; 
                      $this->FULLCODE = "THIS CODE IS NOT EAN/UPC TYPE"; 
                    } 
                 
                  break; 
                case "C25I" : 
                 
                    $long = strlen($this->CODE); 
                    if(($long%2)==0) $this->CODE = '0'.$this->CODE; 
             
                case "C25" : 
                 
                    if (preg_match("/^[0-9]{1,48}$/", $this->CODE)) 
                    { 
                        $checksum = 0; 
                        $factor = 3; 
                        $long = strlen($this->CODE); 
                        for ($i = $long; $i > 0; $i--) { 
                            $checksum += intval($this->CODE{$i-1}) * $factor; 
                            $factor = 4-$factor; 
                        } 
                        $checksum = 10 - ($checksum % 10); 
                        if ($checksum == 10) $checksum = 0; 
                        $this->FULLCODE = $this->CODE.$checksum; 
                    } 
                    else 
                    { 
                      $this->TYPE = "ERR"; 
                      $this->FULLCODE = "CODE C25 REQUIRES DIGITS ONLY"; 
                    } 
                     
                  break; 
                case "C39" : 
                     
                    if (preg_match("/^[0-9A-Z\-\.\$\/+% ]{1,48}$/i", $this->CODE)) 
                    { 
                      $this->FULLCODE = '*'.$this->CODE.'*'; 
                    } 
                    else 
                    { 
                      $this->TYPE = "ERR"; 
                      $this->FULLCODE = "UNAUTHORIZED CHARS IN CODE 39"; 
                    } 
                     
                  break; 
                case "CODABAR" : 
                 
                    if (!preg_match("/^(A|B|C|D)[0-9\-\$:\/\.\+]{1,48}(A|B|C|D)$/i", $this->CODE)) 
                    { 
                      $this->TYPE = "ERR"; 
                      $this->FULLCODE = "CODABAR START/STOP : ABCD"; 
                    } 
                    else $this->FULLCODE = $this->CODE; 
                     
                  break; 
                case "MSI" : 
                 
                    if (preg_match("/^[0-9]{1,48}$/", $this->CODE)) 
                    { 
                        $checksum = 0; 
                        $factor = 1; 
                        $tmp = strlen($this->CODE); 
                        for ($i = 0; $i < $tmp; $i++) { 
                            $checksum += intval($this->CODE{$i}) * $factor; 
                            $factor++; 
                            if ($factor > 10) $factor = 1;  
                        } 
                        $checksum = (1000 - $checksum) % 10; 
                        $this->FULLCODE = $this->CODE.$checksum; 
                    } 
                    else 
                    { 
                      $this->TYPE = "ERR"; 
                      $this->FULLCODE = "CODE MSI REQUIRES DIGITS ONLY"; 
                    } 
                     
                  break; 
                case "C11" : 
                 
                    if (preg_match("/^[0-9\-]{1,48}$/", $this->CODE)) 
                    { 
                        $checksum = 0; 
                        $factor = 1; 
                        $tmp = strlen($this->CODE); 
                        for ($i = $tmp; $i > 0; $i--) { 
                            $tmp = $this->CODE{$i-1}; 
                            if ($tmp == "-") $tmp = 10; 
                            else $tmp = intval($tmp); 
                            $checksum += ($tmp * $factor); 
                            $factor++;  
                            if ($factor > 10) $factor=1; 
                        } 
                        $checksum = $checksum % 11; 
                        if ($checksum == 10) $this->FULLCODE = $this->CODE . "-"; 
                        else $this->FULLCODE .= $this->CODE.$checksum; 
                    } 
                    else 
                    { 
                      $this->TYPE = "ERR"; 
                      $this->FULLCODE = "UNAUTHORIZED CHARS IN CODE 11"; 
                    } 
                     
                  break; 
                case "POSTNET" : 
                 
                    if (preg_match("/^[0-9]{5}$/", $this->CODE) OR preg_match("/^[0-9]{9}$/", $this->CODE) OR preg_match("/^[0-9]{11}$/", $this->CODE)) 
                    { 
                        $checksum = 0; 
                        $tmp = strlen($this->CODE); 
                        for ($i = $tmp; $i > 0; $i--) { 
                            $checksum += intval($this->CODE{$i-1}); 
                        } 
                        $checksum = 10 - ($checksum % 10); 
                        if($checksum == 10) $checksum = 0; 
                        $this->FULLCODE = $this->CODE.$checksum; 
                    } 
                    else 
                    { 
                      $this->TYPE = "ERR"; 
                      $this->FULLCODE = "POSTNET MUST BE 5/9/11 DIGITS"; 
                    } 
                     
                  break; 
                case "KIX" : 
                 
                    if (preg_match("/^[A-Z0-9]{1,50}$/", $this->CODE)) 
                    { 
/* ***** LE CODE KIX n'a pas de checksum 
                        $checksum = 0; 
                        $tmp = strlen("$this->CODE"); 
                        for($i=$tmp-1; $i>=0; $i--) { 
                            $checksum += intval(substr($this->CODE,$i,1)); 
                        } 
                        $checksum = 10-($checksum%10); 
                        if($checksum==10) $checksum=0; 
                        $this->CODE .= "$checksum"; 
*/ 
                        $this->FULLCODE = $this->CODE; 
                    } 
                    else 
                    { 
                      $this->TYPE = "ERR"; 
                      $this->FULLCODE = "UNAUTHORIZED CHARS IN KIX CODE"; 
                    } 
                     
                  break; 
                case "CMC7" : 
                 
                    if(!preg_match("/^[0-9A-E]{1,48}$/", $this->CODE)) { 
                      $this->TYPE = "ERR"; 
                      $this->FULLCODE = "CMC7 MUST BE NUMERIC or ABCDE"; 
                    } 
                    else $this->FULLCODE = $this->CODE; 
                     
                  break; 
                default : 
                 
                    $this->TYPE = "ERR"; 
                    $this->FULLCODE = "UNKWOWN BARCODE TYPE"; 
                     
                  break; 
            } 
        } 
         
        /** 
        * Encodage 
        *  
        * Encode des symboles (a-Z, 0-9, ...) vers des barres 
        */ 
        function encode() 
        { 
            settype($this->FULLCODE, 'string'); 
            $lencode = strlen($this->FULLCODE); 
             
            $encodedString = ''; 
             
            // Copie de la chaine dans un tableau 
            $a_tmp = array(); 
            for($i = 0; $i < $lencode ; $i++) $a_tmp[$i] = $this->FULLCODE{$i}; 
     
            switch( $this->TYPE ) { 
             
                case "EAN" : 
                case "UPC" : 
                    if ($lencode == 8) 
                    { 
                        $encodedString = '101'; //Premier sÃ©parateur (101) 
                        for ($i = 0; $i < 4; $i++) $encodedString .= $this->EANbars['A'][$a_tmp[$i]]; //Codage partie gauche (tous de classe A) 
                        $encodedString .= '01010'; //SÃ©parateur central (01010) //Codage partie droite (tous de classe C)
                        for ($i = 4; $i < 8; $i++) $encodedString .= $this->EANbars['C'][$a_tmp[$i]]; 
                        $encodedString .= '101'; //Dernier sÃ©parateur (101) 
                    } 
                    else 
                    { 
                        $parity = $this->EANparity[$a_tmp[0]]; //On rÃ©cupÃ¨re la classe de codage de la partie qauche 
                        $encodedString = '101'; //Premier sÃ©parateur (101) 
                        for ($i = 1; $i < 7; $i++) $encodedString .= $this->EANbars[$parity[$i-1]][$a_tmp[$i]]; //Codage partie gauche 
                        $encodedString .= '01010'; //SÃ©parateur central (01010) //Codage partie droite (tous de classe C)
                        for ($i = 7; $i < 13; $i++) $encodedString .= $this->EANbars['C'][$a_tmp[$i]]; 
                        $encodedString .= '101'; //Dernier sÃ©parateur (101) 
                    } 
         
                  break; 
                case "C128C" : 
                    $encodedString = $this->C128['C']; //Start 
                    $checksum = 105 ; 
                    $j = 1 ; 
                    for ($i = 0; $i < $lencode; $i += 2) 
                    { 
                        $tmp = intval(substr($this->FULLCODE, $i, 2)) ; 
                        $checksum += ( $j++ * $tmp ) ; 
                        $encodedString .= $this->C128[$tmp]; 
                    } 
                    $checksum %= 103 ; 
                    $encodedString .= $this->C128[$checksum]; 
                    $encodedString .= $this->C128['S']; //Stop 
                  break; 
                case "C128" : 
                    $encodedString = $this->C128['B']; //Start 
                    $checksum = 104 ; 
                    $j = 1 ; 
                    for ($i = 0; $i < $lencode; $i++) 
                    { 
                        $tmp = ord($a_tmp[$i]) - 32 ; 
                        $checksum += ( $j++ * $tmp ) ; 
                        $encodedString .= $this->C128[$tmp]; 
                    } 
                    $checksum %= 103 ; 
                    $encodedString .= $this->C128[$checksum]; 
                    $encodedString .= $this->C128['S']; //Stop 
                  break; 
                case "C25" : 
                    $encodedString = $this->C25['D']."0"; //Start 
                    for ($i = 0; $i < $lencode; $i++) 
                    { 
                        $num = intval($a_tmp[$i]) ; 
                        $tmp = $this->C25[$num]; 
                        for ($j = 0; $j < 5; $j++) 
                        { 
                            $tmp2 = intval(substr($tmp,$j,1)) ; 
                            for ($k = 1; $k <= $tmp2; $k++) $encodedString .= "1"; 
                            $encodedString .= "0"; 
                        } 
                    } 
                    $encodedString .= $this->C25['F']; //Stop 
                  break; 
                case "C25I" : 
                    $encodedString = $this->C25['d']; //Start 
                    $checksum = 0; 
                    for ($i = 0; $i < $lencode; $i += 2) 
                    { 
                        $num1 = intval($a_tmp[$i]) ; 
                        $num2 = intval($a_tmp[$i+1]) ; 
                        $checksum += ($num1+$num2); 
                        $tmp1 = $this->C25[$num1]; 
                        $tmp2 = $this->C25[$num2]; 
                        for ($j = 0; $j < 5; $j++) 
                        { 
                            $t1 = intval(substr($tmp1, $j, 1)) ; 
                            $t2 = intval(substr($tmp2, $j, 1)) ; 
                            for ($k = 1; $k <= $t1; $k++) $encodedString .= "1"; 
                            for ($k = 1; $k <= $t2; $k++) $encodedString .= "0"; 
                        } 
                    } 
                    $encodedString .= $this->C25['f']; //Stop 
                  break; 
                case "C39" : 
                    for ($i = 0; $i < $lencode; $i++)$encodedString .= $this->C39[$a_tmp[$i]] . "0"; 
                    $encodedString = substr($encodedString, 0, -1); 
                  break; 
                case "CODABAR" : 
                    for ($i = 0; $i < $lencode; $i++) $encodedString .= $this->codabar[$a_tmp[$i]] . "0"; 
                    $encodedString = substr($encodedString, 0, -1); 
                  break; 
                case "MSI" : 
                    $encodedString = $this->MSI['D']; //Start 
                    for ($i = 0; $i < $lencode; $i++) $encodedString .= $this->MSI[intval($a_tmp[$i])]; 
                    $encodedString .= $this->MSI['F']; //Stop 
                  break; 
                case "C11" : 
                    $encodedString = $this->C11['S']."0"; //Start 
                    for ($i = 0; $i < $lencode; $i++) $encodedString .= $this->C11[$a_tmp[$i]]."0"; 
                    $encodedString .= $this->C11['S']; //Stop 
                  break; 
                case "POSTNET" : 
                    $encodedString = '1'; //Start 
                    for ($i = 0; $i < $lencode; $i++) $encodedString .= $this->postnet[$a_tmp[$i]]; 
                    $encodedString .= '1'; //Stop 
                     
                    $this->CODEWIDTH = ( strlen($encodedString) * 4 ) - 4; 
                    if( $this->HR != '' ) $this->HEIGHT = 32; 
                    else $this->HEIGHT = 22; 
                  break; 
                case "KIX" : 
//                    $encodedString = "31"; //Start 
                    for ($i = 0; $i < $lencode; $i++) $encodedString .= $this->kix[$a_tmp[$i]]; 
//                    $encodedString .= "32"; //Stop 
                     
                    $this->CODEWIDTH = ( strlen($encodedString) * 4 ) - 4; 
                    if( $this->HR != '' ) $this->HEIGHT = 32; 
                    else $this->HEIGHT = 22; 
                  break; 
                case "CMC7" : 
                    $encodedString = $this->FULLCODE; 
                                     
                    $this->CODEWIDTH = ( $lencode * 24 ) - 8; 
                    $this->HEIGHT = 35; 
                  break; 
                case "ERR" : 
                    $encodedString = ''; 
                                     
                    $this->CODEWIDTH = (imagefontwidth(2) * $lencode); 
                    $this->HEIGHT = max( $this->HEIGHT, 36 ); 
                  break; 
                   
            } 
     
            $nb_elem = strlen($encodedString); 
            $this->CODEWIDTH = max( $this->CODEWIDTH, $nb_elem ); 
            $this->WIDTH = max( $this->WIDTH, $this->CODEWIDTH + ($this->CALMZONE*2) ); 
            $this->ENCODED = $encodedString; 
         
         
            /** 
            * CrÃ©ation de l'image du code 
            */ 
             
            //Initialisation de l'image 
            $txtPosX = $posX = intval(($this->WIDTH - $this->CODEWIDTH)/2); // position X 
            $posY = 0; // position Y 
            $intL = 1; // largeur de la barre 
             
            // detruire eventuellement l'image existante 
            if ($this->IH) imagedestroy($this->IH); 
             
            // TODO Aqui para aumentar a base
            $this->IH = imagecreate($this->WIDTH, $this->HEIGHT + 2); 
             
            // colors 
            $color[0] = ImageColorAllocate($this->IH, 0xFF & ($this->BACKGROUND >> 0x10), 0xFF & ($this->BACKGROUND >> 0x8), 0xFF & $this->BACKGROUND); 
            $color[1] = ImageColorAllocate($this->IH, 0xFF & ($this->FOREGROUND >> 0x10), 0xFF & ($this->FOREGROUND >> 0x8), 0xFF & $this->FOREGROUND); 
            $color[2] = ImageColorAllocate($this->IH, 160,160,160); // greyed 
             
            imagefilledrectangle($this->IH, 0, 0, $this->WIDTH, $this->HEIGHT, $color[0]); 
             
             
            // Gravure du code 
            for ($i = 0; $i < $nb_elem; $i++) 
            { 
             
                // Hauteur des barres dans l'image 
                $intH = $this->HEIGHT;  
                if( $this->HR != '' ) 
                { 
                    switch ($this->TYPE) 
                    { 
                      case "EAN" : 
                      case "UPC" : 
                        if($i<=2 OR $i>=($nb_elem-3) OR ($i>=($nb_elem/2)-2 AND $i<=($nb_elem/2)+2)) $intH-=6; else $intH-=11; 
                      break; 
                      default : 
                        if($i>0 AND $i<($nb_elem-1)) $intH-=11; 
                    } 
                } 
                 
                // Gravure des barres 
                $fill_color = $this->ENCODED{$i}; 
                switch ($this->TYPE) 
                { 
                  case "POSTNET" : 
                    if($fill_color == "1") imagefilledrectangle($this->IH, $posX, ($posY+1), $posX+1, ($posY+20), $color[1]); 
                    else imagefilledrectangle($this->IH, $posX, ($posY+12), $posX+1, ($posY+20), $color[1]); 
                    $intL = 4 ; 
                  break; 
                  case "KIX" : 
                    if($fill_color == "0") imagefilledrectangle($this->IH, $posX, ($posY+1), $posX+1, ($posY+13), $color[1]); 
                    elseif($fill_color == "1") imagefilledrectangle($this->IH, $posX, ($posY+7), $posX+1, ($posY+19), $color[1]); 
                    elseif($fill_color == "2") imagefilledrectangle($this->IH, $posX, ($posY+7), $posX+1, ($posY+13), $color[1]); 
                    else imagefilledrectangle($this->IH, $posX, ($posY+1), $posX+1, ($posY+19), $color[1]); 
                    $intL = 4 ; 
                  break; 
                  case "CMC7" : 
                    $tmp = $this->CMC7[$fill_color]; 
                    $coord = explode( "|", $tmp ); 
                     
                    for ($j = 0; $j < sizeof($coord); $j++) 
                    { 
                        $pts = explode( "-", $coord[$j] ); 
                        $deb = explode( ",", $pts[0] ); 
                        $X1 = $deb[0] + $posX ; 
                        $Y1 = $deb[1] + 5 ; 
                        $fin = explode( ",", $pts[1] ); 
                        $X2 = $fin[0] + $posX ; 
                        $Y2 = $fin[1] + 5 ; 
                         
                        imagefilledrectangle($this->IH, $X1, $Y1, $X2, $Y2, $color[1]); 
                    } 
                    $intL = 24 ; 
                  break; 
                  default : 
                    if($fill_color == "1") imagefilledrectangle($this->IH, $posX, $posY, $posX, ($posY+$intH), $color[1]); 
                } 
                 
                //Deplacement du pointeur 
                $posX += $intL; 
            } 
             
            // Ajout du texte 
            $ifw = imagefontwidth(3); 
            // TODO Para aumentar o texto visível
            $ifh = imagefontheight(4) - 1; 
             
            $text = ($this->HR == 'AUTO' ? $this->CODE : $this->HR); 
             
            switch ($this->TYPE) 
            { 
              case "ERR" : 
                $ifw = imagefontwidth(3); 
                imagestring($this->IH, 3, floor( (($this->WIDTH)-($ifw * 7)) / 2 ), 1, "ERROR :", $color[1]);  
                imagestring($this->IH, 2, 10, 13, $this->FULLCODE, $color[1]);  
                $ifw = imagefontwidth(1); 
                imagestring($this->IH, 1, ($this->WIDTH)-($ifw * 9)-2, $this->HEIGHT - $ifh, "", $color[2]);  
              break; 
              case "EAN" : 
                    if ($text != '') if((strlen($this->FULLCODE) > 10) && ($this->FULLCODE{0} > 0)) imagestring($this->IH, 3, $txtPosX-7, $this->HEIGHT - $ifh, substr($this->FULLCODE,-13,1), $color[1]);  
              case "UPC" : 
                if ($text != '')  
                { 
                    if(strlen($this->FULLCODE) > 10) { 
                        imagestring($this->IH, 3, $txtPosX+4, $this->HEIGHT - $ifh, substr($this->FULLCODE,1,6), $color[1]);  
                        imagestring($this->IH, 3, $txtPosX+50, $this->HEIGHT - $ifh, substr($this->FULLCODE,7,6), $color[1]);  
                    } else { 
                        imagestring($this->IH, 3, $txtPosX+4, $this->HEIGHT - $ifh, substr($this->FULLCODE,0,4), $color[1]);  
                        imagestring($this->IH, 3, $txtPosX+36, $this->HEIGHT - $ifh, substr($this->FULLCODE,4,4), $color[1]);  
                    } 
                } 
              break; 
              case "CMC7" : 
              break; 
              default : 
              	// TODO Para alterar a posição do texto
                if ($text != '') imagestring($this->IH, 4, intval((($this->WIDTH)-($ifw * strlen($text)))/2)+1, $this->HEIGHT - $ifh + 3, $this->CODE, $color[1]);  
            } 
             
            $ifw = imagefontwidth(1) * 9; 
            if ((rand(0,50)<1) AND ($this->HEIGHT >= $ifw)) imagestringup($this->IH, 1, $nb_elem + 12, $this->HEIGHT - 2, "", $color[2]); 
             
            // impression du type de code (si demandÃ©) 
            if ($this->SHOWTYPE == 'Y') 
            { 
                if (($this->TYPE == "EAN") AND (strlen($this->FULLCODE) > 10) AND ($this->FULLCODE{0} > 0) AND ($text != '')) 
                { 
                    imagestringup($this->IH, 1, 0, $this->HEIGHT - 12, $this->TYPE, $color[2]);  
                } 
                elseif ($this->TYPE == "POSTNET") 
                { 
                    imagestringup($this->IH, 1, 0, $this->HEIGHT - 2, "POST", $color[2]);  
                } 
                elseif ($this->TYPE != "ERR") 
                { 
                    imagestringup($this->IH, 1, 0, $this->HEIGHT - 2, $this->TYPE, $color[2]);  
                } 
            } 
        } 
             
         
        /** 
        * Show Image 
        */ 
        function showBarcodeImage() 
        { 
            $this->checkCode(); 
            $this->encode(); 

            if ($this->FILETYPE == 'GIF')  
            { 
                Header( "Content-type: image/gif"); 
                imagegif($this->IH);  
            } 
            elseif ($this->FILETYPE == 'JPG')  
            { 
                Header( "Content-type: image/jpeg"); 
                imagejpeg($this->IH);  
            } 
            else 
            { 
                Header( "Content-type: image/png"); 
                imagepng($this->IH);  
            } 
        } 
         
        /** 
        * Save Image 
        */ 
        function writeBarcodeFile($file) 
        { 
            $this->checkCode(); 
            $this->encode(); 

            if ($this->FILETYPE == 'GIF')     imagegif($this->IH, $file); 
            elseif ($this->FILETYPE == 'JPG') imagejpeg($this->IH, $file); 
            else                              imagepng($this->IH, $file); 
        } 
                 
    } 
?>